package com.net.udp
{
	import flash.events.NetStatusEvent;
	import flash.net.GroupSpecifier;
	import flash.net.NetConnection;
	import flash.net.NetGroup;

	public class NetGroupManager
	{
		private static var _instance:NetGroupManager;
		private var _url:String;
		private var _netConnect:NetConnection;
		private var _groupList:Object = {};
		private var _callbackList:Object = {};
		private var _connectSuccess:Function;
		
		public static function getInstance():NetGroupManager{
			if(!_instance){
				_instance = new NetGroupManager;
			}
			return _instance;
		}
		
		public function NetGroupManager()
		{
		}
		
		public function connect(url:String, connectSuccess:Function):void{
			_netConnect = new NetConnection();
			_netConnect.client = {onBWDone:function():void{
				return;
			}};
			_netConnect.addEventListener(NetStatusEvent.NET_STATUS, netStatusHandler);
			_netConnect.connect(url);
			_connectSuccess = connectSuccess;
		}
		
		private function disconnect():void{
			if(_netConnect)
				_netConnect.close();
		}
		
		private function onDisconnect():void{
			_netConnect.removeEventListener(NetStatusEvent.NET_STATUS, netStatusHandler);
			for(var k:* in _groupList){
				var netGroup:NetGroup = _groupList[k] as NetGroup;
				netGroup.close();
				netGroup.removeEventListener(NetStatusEvent.NET_STATUS, netStatusHandler);
			}
			_netConnect = null;
			_groupList = {};
		}
		
		public function addGroup(groupName:String, callback:Function = null):DynamicNetGroup{
			if(!groupName){
				return null;
			}
			var groupSpecifier:GroupSpecifier;
			groupSpecifier = new GroupSpecifier(groupName);
			groupSpecifier.serverChannelEnabled = true;
			groupSpecifier.objectReplicationEnabled = true;
			groupSpecifier.ipMulticastMemberUpdatesEnabled = true;
			groupSpecifier.routingEnabled = true;
			groupSpecifier.postingEnabled = true;		
			groupSpecifier.multicastEnabled = true;
			
			var netGroup:DynamicNetGroup = new DynamicNetGroup(_netConnect, groupSpecifier.groupspecWithAuthorizations());
			netGroup.name = groupName;
			netGroup.callback = callback;
			netGroup.addEventListener(NetStatusEvent.NET_STATUS, netStatusHandler);
			_groupList[groupName] = netGroup;	
			return netGroup;			
		}
		
		public function getGroup(groupName:String):DynamicNetGroup{
			if(_groupList[groupName]){
				return _groupList[groupName];
			}
			return null;
		}
		
		public function delGroup(groupName:String):void{
			if(_groupList[groupName]){
				(_groupList[groupName] as DynamicNetGroup).close();
				(_groupList[groupName] as DynamicNetGroup).removeEventListener(NetStatusEvent.NET_STATUS, netStatusHandler);
				delete _groupList[groupName];
			}
		}
		
		private function netStatusHandler(event:NetStatusEvent):void
		{
			switch(event.info.code)
			{
				case "NetConnection.Connect.Success":
					// 连接成功
					if(_connectSuccess){
						_connectSuccess();
					}
					break;
				case "NetConnection.Connect.Closed":
				case "NetConnection.Connect.Failed":
				case "NetConnection.Connect.Rejected":
				case "NetConnection.Connect.AppShutdown":
				case "NetConnection.Connect.InvalidApp":
					onDisconnect();
					break;
				case "NetStream.Connect.Success": // e.info.stream
					break;
				case "NetStream.Connect.Rejected": // e.info.stream
				case "NetStream.Connect.Failed": // e.info.stream
					break;
				case "NetGroup.Connect.Success": // e.info.group
					break;
				case "NetGroup.Connect.Rejected": // e.info.group
				case "NetGroup.Connect.Failed": // e.info.group
					break;
				case "NetGroup.Posting.Notify": // e.info.message, e.info.messageID
					break;
				case "NetGroup.SendTo.Notify": // e.info.message, e.info.from, e.info.fromLocal
					var netGroup:DynamicNetGroup = event.currentTarget as DynamicNetGroup;
					if(netGroup.callback){
						netGroup.callback(netGroup, event.info);
					}
					break;
				case "NetGroup.LocalCoverage.Notify": //
				case "NetGroup.Neighbor.Connect": // e.info.neighbor
				case "NetGroup.Neighbor.Disconnect": // e.info.neighbor
				case "NetGroup.MulticastStream.PublishNotify": // e.info.name
				case "NetGroup.MulticastStream.UnpublishNotify": // e.info.name
				case "NetGroup.Replication.Fetch.SendNotify": // e.info.index
				case "NetGroup.Replication.Fetch.Failed": // e.info.index
				case "NetGroup.Replication.Fetch.Result": // e.info.index, e.info.object
				case "NetGroup.Replication.Request": // e.info.index, e.info.requestID
				default:
					break;
			}
		}
		
	}
}